import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  BoxBufferGeometry,
  MeshBasicMaterial,
  TextureLoader,
  AxesHelper,
  Shape,
  BufferGeometry,
  ShapeBufferGeometry,
  MeshPhongMaterial,
  DoubleSide,
  ExtrudeBufferGeometry,
  PointLight,
  AmbientLight,
  Color,
  Group,
  LineBasicMaterial,
  Points,
  PointsMaterial,
} from "three";

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three/src/constants";
import { Line } from "three/src/objects/Line";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let group: Group;
let controls: OrbitControls;

init();
animate();

function init() {
  camera = new PerspectiveCamera(
    70,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.z = 600;
  const light = new PointLight(0xffffff, 0.8);
  camera.add(light);

  let capsule = new Shape()
    .moveTo(-100, -200)
    .lineTo(-100, 200)
    .arc(100, 0, 100, -Math.PI, 0, true)
    .lineTo(100, -200)
    .arc(-100, 0, 100, 0, Math.PI, true);
  capsule.autoClose = true;

  let bufferGeometry = new ShapeBufferGeometry(capsule);
  let extrudeBufferGeometry = new ExtrudeBufferGeometry(capsule, {
    steps: 2,
    depth: 16,
    bevelEnabled: true,
    bevelThickness: 1,
    bevelSize: 1,
    bevelOffset: 0,
    bevelSegments: 1,
  });
  let texture = new TextureLoader().load(require("../static/images/uv_grid_opengl.jpg").default);
  texture.wrapS = texture.wrapT = RepeatWrapping;
  texture.repeat.set(0.003, 0.003);

  scene = new Scene();
  scene.background = new Color(0xf0f0f0);
  group = new Group();
  scene.add(group);

  let material = new MeshPhongMaterial({
    side: DoubleSide,
    // map: texture,
    color: "#f00",
  });
  let extrudeMesh = new Mesh(extrudeBufferGeometry, material);
  group.add(extrudeMesh);

  let flatBufferGeometry = new ShapeBufferGeometry(capsule);
  let flatMesh = new Mesh(
    flatBufferGeometry,
    new MeshPhongMaterial({
      side: DoubleSide,
      color: "#f00",
    })
  );
  flatMesh.translateZ(50);
  group.add(flatMesh);

  let imgBufferGeometry = new ShapeBufferGeometry(capsule);
  let imgMesh = new Mesh(
    imgBufferGeometry,
    new MeshPhongMaterial({
      map: texture,
      side: DoubleSide,
    })
  );
  imgMesh.translateZ(100);
  group.add(imgMesh);

  capsule.autoClose = true;
  let points = capsule.getPoints();
  let spacePoints = capsule.getSpacedPoints(50);
  let pointBufferGeometry = new BufferGeometry().setFromPoints(points)
  let spacePointBufferGeometry = new BufferGeometry().setFromPoints(spacePoints)
  let lineMesh = new Line(pointBufferGeometry, new LineBasicMaterial({
    color: '#f00',
    linewidth: 1,
    side: DoubleSide
  }))
  lineMesh.translateZ(150)
  let spaceLineMesh = new Line(spacePointBufferGeometry, new LineBasicMaterial({
    color: '#f00',
    linewidth: 1,
    side: DoubleSide
  }))
  spaceLineMesh.translateZ(200)
  group.add(lineMesh)
  group.add(spaceLineMesh)

  let particles = new Points(pointBufferGeometry, new PointsMaterial({
    color: '#0f0',
    size: 4
  }))
  particles.translateZ(250)
  group.add(particles)

  let spaceParticles = new Points(spacePointBufferGeometry, new PointsMaterial({
    color: '#0f0',
    size: 4
  }))
  spaceParticles.translateZ(300)
  group.add(spaceParticles)

  let axes = new AxesHelper(500);
  scene.add(axes);

  // let pointLight = new PointLight('#fff', .8)
  // scene.add(pointLight)
  let ambientLight = new AmbientLight("#fff", 0.5);
  scene.add(ambientLight);

  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  controls = new OrbitControls(camera, renderer.domElement);
  // renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);

  //   mesh.rotation.x += 0.005;
  //   mesh.rotation.y += 0.01;

  renderer.render(scene, camera);
}
